package com.mfc.education.service.edu.service.impl;


import com.mfc.education.common.base.result.ResultCodeEnum;
import com.mfc.education.service.base.dto.CourseDto;
import com.mfc.education.service.base.exception.EduException;
import com.mfc.education.service.edu.entity.Course;
import com.mfc.education.service.edu.mapper.CourseMapper;
import com.mfc.education.service.edu.service.CourseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mfc.education.service.edu.service.TeacherService;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mfc.education.common.base.result.R;
import com.mfc.education.service.edu.entity.*;
import com.mfc.education.service.edu.entity.form.CourseInfoForm;
import com.mfc.education.service.edu.entity.vo.*;
import com.mfc.education.service.edu.feign.OssFileService;
import com.mfc.education.service.edu.mapper.*;
import com.mfc.education.service.edu.service.CourseDescriptionService;
import com.mfc.education.service.edu.service.CourseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.omg.CORBA.TRANSACTION_MODE;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;


/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author Mfc
 * @since 2021-07-25
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {


    @Autowired
    private CourseDescriptionMapper courseDescriptionMapper;

    @Autowired
    private VideoMapper videoMapper;
    @Autowired
    private ChapterMapper chapterMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private CourseCollectMapper courseCollectMapper;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private OssFileService ossFileService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public String saveCourseInfo(CourseInfoForm courseInfoForm) {
        Course course = new Course();
        BeanUtils.copyProperties(courseInfoForm, course);
        course.setStatus(Course.COURSE_DRAFT);

        baseMapper.insert(course);
        String courseId = course.getId();

        CourseDescription courseDescription = new CourseDescription();
        courseDescription.setId(courseId);
        courseDescription.setDescription(courseInfoForm.getDescription());
        courseDescriptionMapper.insert(courseDescription);


        return courseId;
    }

    @Override
    public CourseInfoForm getCourseInfoById(String id) {
        CourseInfoForm courseInfoForm = new CourseInfoForm();

        Course course = baseMapper.selectById(id);
        if (course == null) {
            return null;
        }
        BeanUtils.copyProperties(course, courseInfoForm);

        CourseDescription courseDescription = courseDescriptionMapper.selectById(id);
        courseInfoForm.setDescription(courseDescription.getDescription());

        return courseInfoForm;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateCourseInfo(CourseInfoForm courseInfoForm) {
        Course course = new Course();
        BeanUtils.copyProperties(courseInfoForm, course);
        baseMapper.updateById(course);

        CourseDescription courseDescription = new CourseDescription();
        courseDescription.setId(courseInfoForm.getId());
        courseDescription.setDescription(courseInfoForm.getDescription());
        courseDescriptionMapper.updateById(courseDescription);

        return true;
    }

    @Override
    public IPage<CourseVo> selectPage(Long page, Long limit, CourseQueryVo courseQueryVo) {
        // 组装分页
        Page<CourseVo> pageParam = new Page<>(page, limit);

        //查询条件
        QueryWrapper<CourseVo> queryWrapper = new QueryWrapper<>();

        queryWrapper.orderByDesc("c.gmt_create");

        String title = courseQueryVo.getTitle();
        String teacherId = courseQueryVo.getTeacherId();
        String subjectId = courseQueryVo.getSubjectId();
        String subjectParentId = courseQueryVo.getSubjectParentId();

        if (!StringUtils.isEmpty(title)) {
            queryWrapper.like("c.title", title);
        }

        if (!StringUtils.isEmpty(teacherId)) {
            queryWrapper.eq("c.teacher_id", teacherId);
        }
        if (!StringUtils.isEmpty(subjectParentId)) {
            queryWrapper.eq("c.subject_parent_id", subjectParentId);
        }
        if (!StringUtils.isEmpty(subjectId)) {
            queryWrapper.eq("c.subject_id", subjectId);
        }
        // 执行分页查询
        // 分页组件做为mapper的第一个参数，自动实现分页
        // 只需要在mapper层传入封装好的分页组件即可，sql分页条件组装的过程由mp自动完成
        List<CourseVo> records = baseMapper.selectPageByCourseQueryVO(pageParam, queryWrapper);

        // 将结果集设置到pageParam中
        return pageParam.setRecords(records);
    }

    @Override
    public boolean removeCoverById(String id) {

        Course course = baseMapper.selectById(id);
        if (course != null) {
            String cover = course.getCover();
            if (!StringUtils.isEmpty(cover)) {
                R r = ossFileService.removeFile(cover);
                return r.getSuccess();
            }
        }
        return false;
    }

    /**
     * 数据库中外键约束的设置;
     * 互联网分布式项目中不允许使用外键与级联更新，一切设计级联的操作不要依赖数据库层，要在业务层解决
     * 如果业务层解决级联删除功能
     * 那么先删除子表数据，再删除父表数据
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeCourseById(String id) {

        // 根据courseId删除Video(课时)
        QueryWrapper<Video> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.eq("course_id", id);
        videoMapper.delete(videoQueryWrapper);

        // 根据courseId删除Chapter(章节)
        QueryWrapper<Chapter> chapterQueryWrapper = new QueryWrapper<>();
        chapterQueryWrapper.eq("course_id", id);
        chapterMapper.delete(chapterQueryWrapper);

        // 根据courseId删除Comment(评论)
        QueryWrapper<Comment> commentQueryWrapper = new QueryWrapper<>();
        commentQueryWrapper.eq("course_id", id);
        commentMapper.delete(commentQueryWrapper);

        // 根据courseId删除CourseCollect(课程收藏)
        QueryWrapper<CourseCollect> courseCollectQueryWrapper = new QueryWrapper<>();
        courseCollectQueryWrapper.eq("course_id", id);
        courseCollectMapper.delete(courseCollectQueryWrapper);


        // 删除课程详情
        courseDescriptionMapper.deleteById(id);

        // 删除课程
        return this.removeById(id);
    }

    @Override
    public CoursePublishVo getCoursePublishVoById(String id) {
        return baseMapper.selectCoursePublishInfoById(id);
    }

    @Override
    public boolean publishCourseById(String id) {

        // 优化 根据id更新 不需要查询
        Course course = new Course();
        course.setId(id);
        course.setStatus(Course.COURSE_NORMAL);
        return this.updateById(course);
    }

    @Override
    public List<Course> webSelectList(WebCourseQueryVo webCourseQueryVo) {
        String subjectParentId = webCourseQueryVo.getSubjectParentId();
        String subjectId = webCourseQueryVo.getSubjectId();
        String buyCountSort = webCourseQueryVo.getBuyCountSort();
        String gmtCreateSort = webCourseQueryVo.getGmtCreateSort();
        String priceSort = webCourseQueryVo.getPriceSort();


        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        // 查询已发布的课程
        queryWrapper.eq("status", Course.COURSE_NORMAL);
        if (!StringUtils.isEmpty(subjectParentId)) {
            queryWrapper.eq("subject_parent_id", subjectParentId);
        }
        if (!StringUtils.isEmpty(subjectId)) {
            queryWrapper.eq("subject_id", subjectId);
        }
        if (!StringUtils.isEmpty(buyCountSort)) {
            queryWrapper.orderByDesc("buy_count");
        }
        if (!StringUtils.isEmpty(gmtCreateSort)) {
            queryWrapper.orderByDesc("gmt_create");
        }
        if (!StringUtils.isEmpty(priceSort)) {
            if (priceSort.equals("-1")) {
                queryWrapper.orderByAsc("price");
            } else {
                queryWrapper.orderByDesc("price");
            }
        }


        return baseMapper.selectList(queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public WebCourseVo selectWebCourseVoById(String id) {


        // 更新浏览数
        Course course = baseMapper.selectById(id);
        if (course != null) {
            course.setViewCount(course.getViewCount() + 1);
            baseMapper.updateById(course);
        }

        return baseMapper.selectWebCourseVoById(id);
    }

    @Cacheable(value = "index", key = "'selectHotCourse'")
    @Override
    public List<Course> selectHotCourse() {

        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("view_count");
        queryWrapper.last("limit 8");

        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public CourseDto getCourseDtoById(String courseId) {
        return baseMapper.selectCourseDtoById(courseId);
    }

    @Override
    public void updateBuyCountById(String id) {
        Course course = baseMapper.selectById(id);
        long buyCount = course.getBuyCount() + 1;
        course.setBuyCount(buyCount);
        this.updateById(course);
    }

//    @Override
//    public CourseDto getCourseDtoById(String courseId) {
//
//        Course course = baseMapper.selectById(courseId);
//        if (course == null){
//            throw new EduException(ResultCodeEnum.PARAM_ERROR);
//        }
//        String teacherId = course.getTeacherId();
//        Teacher teacher = teacherService.getBaseMapper().selectById(teacherId);
//
//        CourseDto courseDto = new CourseDto();
//        BeanUtils.copyProperties(course, courseDto);
//        courseDto.setTeacherName(teacher.getName());
//
//        return courseDto;
//    }

}
